package java44th.group.config.realm;

import java44th.group.bean.po.*;
import java44th.group.mapper.MarketAdminMapper;
import java44th.group.mapper.MarketPermissionMapper;
import java44th.group.mapper.MarketRoleMapper;
import java44th.group.mapper.MarketUserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @ProjectName project-second
 * @Descriptiom Realm做的事情就是提供 认证信息 和 授权信息
 * @Aurhor: 蔡文强
 * @Since: 2022/10/14 10:49
 */
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    MarketAdminMapper marketAdminMapper;
    @Autowired
    MarketUserMapper marketUserMapper;
    @Autowired
    MarketRoleMapper roleMapper;
    @Autowired
    MarketPermissionMapper permissionMapper;


    // 通常要先认证再授权
    // 所以 doGetAuthenticationInfo方法提到上面
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 通常根据AuthenticationToken中传入的用户名信息查询出该用户在数据库中的信息
        // 因为知道principal第一个参数就是username
        String type = ((MarketToken) authenticationToken).type;
        String username = (String) authenticationToken.getPrincipal();
        // 或者
        // UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        // String username = token.getUsername();

        if ("admin".equals(type)) {
            MarketAdminExample example = new MarketAdminExample();
            example.createCriteria().andUsernameEqualTo(username);
            List<MarketAdmin> marketAdmins = marketAdminMapper.selectByExample(example);
            if (marketAdmins.size() == 1) {
                // 说明数据库中有一条对应的信息
                MarketAdmin marketAdmin = marketAdmins.get(0);
                // 看该方法的返回值，可以知道它现在需要返回一个认证后的信息辣
                // 开始构造认证信息
                // 第一个参数：principals 可以放入你需要的用户信息，该信息会作为Principals，为了方便Subject可以随时取出
                // 第二个参数：凭据credentials 放入一些秘密信息，比如从数据库查到的  真正（正确）的密码
                // 通常这里放用户真正的密码，用于和传进来的token里的密码进行  比对  ，如果一致说明认证成功
                // 这个比对的过程也不需要去写， 认证器会帮忙进行比对
                // 第三个参数realmName 传入相应的realm的域名，没啥用，直接用它父类的getName方法来获得一个realmName
                return new SimpleAuthenticationInfo(marketAdmin, marketAdmin.getPassword(), getName());
            }
        } else if ("user".equals(type)) {
            MarketUserExample marketUserExample = new MarketUserExample();
            marketUserExample.createCriteria().andUsernameEqualTo(username);
            List<MarketUser> marketUsers = marketUserMapper.selectByExample(marketUserExample);
            if(marketUsers.size()==1){
                MarketUser marketUser = marketUsers.get(0);

                return  new SimpleAuthenticationInfo(marketUser,marketUser.getPassword(),getName());

            }


        }

        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 要先获得Principal信息
        MarketAdmin principal = (MarketAdmin) principalCollection.getPrimaryPrincipal();
        // 根据用户信息查询出对应的权限列表   用mybatis来查询  待做！！！！！
        List<String> permissions = new ArrayList<>();
        Integer[] roleIdList = principal.getRoleIds();
        for (Integer roleId : roleIdList) {
            MarketPermissionExample marketPermissionExample = new MarketPermissionExample();
            MarketPermissionExample.Criteria permissionCriteria = marketPermissionExample.createCriteria();
            permissionCriteria.andDeletedEqualTo(false);
            permissionCriteria.andRoleIdEqualTo(roleId);
            List<MarketPermission> marketPermissionList = permissionMapper.selectByExample(marketPermissionExample);
            for (MarketPermission marketPermission : marketPermissionList) {
                permissions.add(marketPermission.getPermission());
            }
        }
        // 注意这个是Author不是AuthenticInfo
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 把所有的钥匙找出来给到授权信息
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }


}
